package com.cxrj.zhsq.utils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期处理工具,线程安全
 */
public class DateUtils {
	private static ThreadLocal<DateFormat> dateFormatStore = new ThreadLocal<DateFormat>();

	public static final String yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
	public static final String yyyyMMdd = "yyyy-MM-dd";
	public static final String yyyy_MM_dd = "yyyy/MM/dd";
	public static final String yyyyMM = "yyyy-MM";
	public static final String yyyy = "yyyy";
	public static final String HHmmss = "HH:mm:ss";
	public static final String MM = "MM";
	public static final String week = "E";

	/**
	 * 返回MongoDB需要的格式date yyyy/MM/dd
	 * 
	 * @return
	 */
	public static Date getMongoCurrentDate() {
		DateFormat format = getDateFormat(yyyy_MM_dd);
		String str = format.format(new Date());
		Date parse = parse(str, yyyy_MM_dd);
		return parse;
	}

	/**
	 * 获取具体时间的年月日时分
	 * 
	 * @param type 不同种类
	 * @return
	 */
	public static String getDateYMDHM(String type) {
		String time = DateUtils.ymdhmsFormat(new Date());
		String year = time.split(" ")[0].split("-")[0];
		String month = time.split(" ")[0].split("-")[1];
		String day = time.split(" ")[0].split("-")[2];
		String hour = time.split(" ")[1].split(":")[0];
		String minute = time.split(" ")[1].split(":")[1];
		String second = time.split(" ")[1].split(":")[2];

		if (type.equals("year")) {
			return year;
		} else if (type.equals("month")) {
			return month;
		} else if (type.equals("day")) {
			return day;
		} else if (type.equals("hour")) {
			return hour;
		} else if (type.equals("minute")) {
			return minute;
		} else {
			return second;
		}
	}

	/**
	 * 通过格式获取格式化对象,线程安全
	 * 
	 * @param datePattern
	 * @return
	 */
	public static DateFormat getDateFormat(String datePattern) {
		DateFormat fmt = dateFormatStore.get();
		if (fmt == null) {
			fmt = new SimpleDateFormat(datePattern);
			dateFormatStore.set(fmt);
		}
		return fmt;
	}

	/**
	 * 将字符串日期转换成Date对象
	 * 
	 * @param dateStr     日期字符串
	 * @param datePattern 日期格式
	 * @return
	 */
	public static Date parse(String dateStr, String datePattern) {
		try {
			return getDateFormat(datePattern).parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 将Date对象转换成字符串日期
	 * 
	 * @param date        日期对象
	 * @param datePattern 日期格式
	 * @return
	 */
	public static String format(Date date, String datePattern) {
		return getDateFormat(datePattern).format(date);
	}

	/**
	 * 取得特定时间对应的字符串,格式化为yyyy-MM-dd HH:mm:ss
	 * 
	 * @param date 日期对象
	 * @return
	 */
	public static String ymdhmsFormat(Date date) {
		return format(date, yyyyMMddHHmmss);
	}

	/**
	 * 取得特定时间对应的字符串,格式化为yyyy-MM-dd
	 * 
	 * @param date
	 * @return
	 */
	public static String ymdFormat(Date date) {
		return format(date, yyyyMMdd);
	}

	/**
	 * 根据当前日期,得到当前年月
	 * 
	 * @param date
	 * @return str
	 */
	public static final String ymFormat(Date date) {
		if (date == null)
			return "";
		return format(date, yyyyMM);
	}

	/**
	 * 根据当前日期,得到当前年份
	 * 
	 * @param date
	 * @return str
	 */
	public static final String yFormat(Date date) {
		if (date == null)
			return "";
		return format(date, yyyy);
	}

	/**
	 * 根据当前日期,得到当前月份
	 * 
	 * @param date
	 * @return str
	 */
	public static final String mFormat(Date date) {
		if (date == null)
			return "";
		return format(date, MM);
	}

	/**
	 * 返回当前的时间，格式为H:mm:ss
	 * 
	 * @return 时间字符串
	 */
	public static final String getTimeNow() {
		return format(new Date(), HHmmss);
	}

	/**
	 * 把字符串形式转换成日期形式，字符串的格式必须为yyyy-MM-dd
	 * 
	 * @param ymdStringDate
	 * @return date
	 */
	public static final Date ymdString2Date(String ymdStringDate) {
		if (ymdStringDate == null)
			return null;
		return parse(ymdStringDate, yyyyMMdd);
	}

	/**
	 * 把字符串形式转换成日期形式，字符串的格式必须为yyyy-MM-dd
	 * 
	 * @param ymdhmsStringDate
	 * @return date
	 */
	public static final Date ymdhmsString2Date(String ymdhmsStringDate) {
		if (ymdhmsStringDate == null)
			return null;
		return parse(ymdhmsStringDate, yyyyMMddHHmmss);
	}

	/**
	 * 
	 * 得到当前时间,把日期后的时间归0 变成(yyyy-MM-dd 00:00:00:000)
	 * 
	 * @return date
	 */
	public static Date getCurrentDate() {
		Date date = new Date();
		return zerolizedTime(date);
	}

	/**
	 * 把日期后的时间归0 变成(yyyy-MM-dd 00:00:00:000)
	 * 
	 * @param fullDate
	 * @return Date
	 */
	public static final Date zerolizedTime(Date fullDate) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(fullDate);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 得到两个时间的间隔
	 * 
	 * @param bDate
	 * @param eDate
	 * @return
	 */
	static public long dateDiffByDay(Date bDate, Date eDate) {
		if (bDate == null || eDate == null)
			return 0L;
		return (bDate.getTime() - eDate.getTime()) / (1000 * 3600 * 24);
	}

	/**
	 * 取得指定日期的星期数
	 * 
	 * @return String
	 */
	public static final String getWeek(Date date) {
		if (date == null)
			return null;
		return format(date, week);
	}

	/**
	 * 判断两个日期字符串是否相等,格式必需为yyyy-MM-dd
	 * 
	 * @param one 第一个日期字符串
	 * @param two 第二个日期字符串
	 * @return Boolean
	 */
	public static final boolean isEqual(String one, String two) {
		return ymdString2Date(one).equals(ymdString2Date(two));
	}

	/**
	 * 判断两个日期字符串是否相等
	 * 
	 * @param one         第一个日期字符串
	 * @param two         第二个日期字符串
	 * @param datePattern 包含日期格式的字符串
	 * @return Boolean
	 */
	public static final boolean isEqual(String one, String two, String datePattern) {

		return isEqual(one, two, datePattern, datePattern);
	}

	/**
	 * 判断两个日期字符串是否相等
	 * 
	 * @param one            第一个日期字符串
	 * @param two            第二个日期字符串
	 * @param datePatternOne 对应第一个日期字符串的包含日期格式的字符串
	 * @param datePatternTwo 对应第二个日期字符串的包含日期格式的字符串
	 * @return Boolean
	 */
	public static final Boolean isEqual(String one, String two, String datePatternOne, String datePatternTwo) {

		return parse(one, datePatternOne).equals(parse(two, datePatternTwo));
	}

	/**
	 * 返回两时间的时间间隔（以分计算）
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	static public long spaceMinute(Date date1, Date date2) {
		Long num1 = date1.getTime();
		Long num2 = date2.getTime();
		Long space = (num2 - num1) / (1000 * 60);
		return space;
	}

	/**
	 * 返回两时间的时间间隔（以天计算）
	 * 
	 * @param time1
	 * @param time2
	 * @return
	 */
	static public Long spaceDay(Date date1, Date date2) {
		Long num1 = date1.getTime();
		Long num2 = date2.getTime();
		Long space = (num2 - num1) / (1000 * 3600 * 24);
		return space;
	}

	static public Date getDateAfterDay(Date somedate, int day) {
		if (somedate == null)
			return null;
		Calendar cal = Calendar.getInstance();
		cal.setTime(somedate);
		cal.add(Calendar.DAY_OF_MONTH, day);
		return new Date(cal.getTime().getTime());
	}

	static public Timestamp getDateAfterDay(int day) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DAY_OF_MONTH, day);
		return new Timestamp(cal.getTime().getTime());
	}

	static public Timestamp getTSAfterDay(Date somedate, int day) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(somedate);
		cal.add(Calendar.DAY_OF_MONTH, day);
		return new Timestamp(cal.getTime().getTime());
	}

	// 取得本月第一天时间
	static public Date getFirstDayOfMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		return cal.getTime();
	}

	// 由出生日期获得年龄
	public static int getAge(Date birthDay) {
		Calendar cal = Calendar.getInstance();

		if (cal.before(birthDay)) {
			throw new IllegalArgumentException("非法数据，生日不可能比现在时间大！");
		}
		int yearNow = cal.get(Calendar.YEAR);
		int monthNow = cal.get(Calendar.MONTH);
		int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
		cal.setTime(birthDay);

		int yearBirth = cal.get(Calendar.YEAR);
		int monthBirth = cal.get(Calendar.MONTH);
		int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

		int age = yearNow - yearBirth;

		if (monthNow <= monthBirth) {
			if (monthNow == monthBirth) {
				if (dayOfMonthNow < dayOfMonthBirth)
					age--;
			} else {
				age--;
			}
		}
		return age;
	}

	/**
	 * 获取当前日期的时间
	 * 
	 * @return
	 */
	public static String getTodayDateStr() {
		Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
		calendar.add(Calendar.DATE, 0); // 得到前一天
		return format(calendar.getTime(), yyyyMMdd);
	}

	/**
	 * 获取当前日期前一天的时间
	 * 
	 * @return
	 */
	public static String getYesterdayDateStr() {
		Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
		calendar.add(Calendar.DATE, -1); // 得到前一天

		return format(calendar.getTime(), yyyyMMdd);
	}

	/**
	 * 获取当前日期后一天的时间
	 * 
	 * @return
	 */
	public static String getTomorrowDateStr() {
		Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
		calendar.add(Calendar.DATE, +1); // 得到前一天

		return format(calendar.getTime(), yyyyMMdd);
	}

	/**
	 * 获取指定日期的后一天
	 * 
	 * @param dateStr 指定日期
	 * @return
	 */
	public static Date getTomorrowDateStr(String dateStr) {
		Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
		calendar.setTime(parse(dateStr, yyyyMMdd));
		calendar.add(Calendar.DATE, 1);
		return calendar.getTime();
	}

	/**
	 * 获取两个日期相差的月数
	 * 
	 * @param d2 较大的日期
	 * @param d1 较小的日期
	 * @return 如果d1>d2返回 月数差 否则返回0
	 * @throws ParseException
	 */
	public static Integer getMonthDiff(String d1, String d2) throws ParseException {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date1 = sdf.parse(d1);
		Date date2 = sdf.parse(d2);
		c1.setTime(date1);
		c2.setTime(date2);
		if (c2.getTimeInMillis() < c1.getTimeInMillis()) {
			return 0;
		}
		int year1 = c1.get(Calendar.YEAR);
		int year2 = c2.get(Calendar.YEAR);
		int month1 = c1.get(Calendar.MONTH);
		int month2 = c2.get(Calendar.MONTH);
		int day1 = c1.get(Calendar.DAY_OF_MONTH);
		int day2 = c2.get(Calendar.DAY_OF_MONTH);
		int yearInterval = year2 - year1;
		if (month2 < month1 || month1 == month2 && day2 < day1) {
			yearInterval--;
		}
		int monthInterval = (month2 + 12) - month1;
		if (day2 > day1) {
			monthInterval++;
		}
		monthInterval %= 12;
		return yearInterval * 12 + monthInterval;
	}
	/**
     * 指定日期加上月份
     * @param olddate
     * @param recordDate
     * @return
     * @throws ParseException
     */
    public static String getnewDate(Date olddate, String recordDate) throws ParseException {
        Date  date  = olddate;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String data = format.format(date);
        String dataStr[] = data.split("-");
        //年份
        int   year = (Integer.parseInt(dataStr[1]) + Integer.parseInt(recordDate))/12;
        //月份
        int  yue =  (Integer.parseInt(dataStr[1]) + Integer.parseInt(recordDate))%12;
        String a = "";
        if(yue<10){
            if(yue<1){
                a = "12";
            }else{
                a = "0"+ yue;
            }
        }else {
            a = yue + "";
        }
        dataStr[0]=String.valueOf(Integer.parseInt(dataStr[0]) + year);
        dataStr[1]=a;
        String  newdata  = dataStr[0]+"-"+dataStr[1]+"-"+dataStr[2];
        Date newDate = format.parse(newdata);
        String enddate = format.format(newDate);
        return  enddate;
    }
}
